#include <fstream>
#include <sstream>
#include <vector>
// include headers that implement a archive in simple text format
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/serialization/vector.hpp>
/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
//
class gps_position
{
private:
	friend class boost::serialization::access;
	// When the class Archive corresponds to an output archive, the
	// & operator is defined similar to <<.  Likewise, when the class Archive
	// is a type of input archive the & operator is defined similar to >>.
	template<class Archive>
	void serialize(Archive &ar, const unsigned int version)
	{
		std::cout << "version=" << version << ":";
		ar & degrees;
		ar & minutes;
		ar & seconds;
		ar & v;
	}
public:
	gps_position(){};
	gps_position(int d, int m, float s) 
		: degrees(d), minutes(m), seconds(s)
	{}
	int degrees;
	int minutes;
	float seconds;
	std::vector<int> v;
};
BOOST_CLASS_VERSION(gps_position, 123);
int main(int argc, char* argv[]) 
{
	if (argc < 2) {
		std::cout << "usage: hello 0 ===>text mode" << std::endl;
		std::cout << "usage: hello 1 ===>binary mode" << std::endl;
		return 0;
	}
	std::stringstream ss;
	gps_position g(123456789, 987654321, 24.567f);
	g.v.push_back(3);
	g.v.push_back(9);
	std::cout << "g:" << g.degrees << '\t' << g.minutes << '\t' << g.seconds << ",";
	std::copy(g.v.begin(), g.v.end(), std::ostream_iterator<int>(std::cout, ","));
	std::cout << std::endl;
	int mode = boost::lexical_cast<int>(argv[1]);
	switch(mode) {
		case 0:
		{
			boost::archive::text_oarchive oa(ss);
			oa & g;
		}
		break;
		case 1:
		{
			boost::archive::binary_oarchive oa(ss);
			oa << g;
		}
		break;
	}
	std::cout << "serializated=" << ss.str() << std::endl;
	std::cout << "length=" << ss.str().length() << std::endl;
	std::vector<unsigned char> v;
	std::cout << "length=" << ss.gcount() << std::endl;
	v.resize(ss.str().length());
	ss.read((char*)&v.at(0), v.size());
	std::stringstream ss2;
	ss2.write((const char*)&v.at(0), v.size());
	gps_position newg;
	switch(mode) {
		case 0:
		{
			boost::archive::text_iarchive ia(ss2);
			ia & newg;
		}
		break;
		case 1:
		{
			boost::archive::binary_iarchive ia(ss2);
			ia >> newg;
		}
		break;
	}
	std::cout << "newg:" << newg.degrees << '\t' << newg.minutes << '\t' << newg.seconds << ",";
	std::copy(g.v.begin(), g.v.end(), std::ostream_iterator<int>(std::cout, ","));
	std::cout << std::endl;
	return 0;
}

